home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / clients / bitmap / bitmap.c < prev    next >
C/C++ Source or Header  |  1994-08-12  |  51KB  |  1,913 lines

  1. /*
  2.  * $XConsortium: Bitmap.c,v 1.38 91/07/24 15:46:52 converse Exp $
  3.  *
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Davor Matic, MIT X Consortium
  24.  */
  25.  
  26. #ifdef MSDOS
  27. #include "X11/IntrinsP.h"      /* QDK 05/11/1994 10:44am. */
  28. #else
  29. #include "X11/IntrinsicP.h"
  30. #endif
  31. #include <X11/StringDefs.h>
  32. #include <X11/Xaw/XawInit.h>
  33. #include <X11/Xmu/CharSet.h>
  34. #include <X11/Xmu/Drawing.h>
  35. #include <X11/Xatom.h>
  36. #include <X11/Xfuncs.h>
  37. #include <X11/Xos.h>
  38. #include "BitmapP.h"
  39.     
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <math.h>
  43.  
  44. #ifndef abs
  45. #define abs(x)                        ((((int)(x)) > 0) ? (x) : -(x))
  46. #endif
  47. #define min(x, y)                     ((((int)(x)) < (int)(y)) ? (x) : (y))
  48. #define max(x, y)                     ((((int)(x)) > (int)(y)) ? (x) : (y))
  49.  
  50. Boolean DEBUG;
  51.  
  52. #define DefaultGridTolerance 8
  53. #define DefaultBitmapSize    "16x16"
  54. #define FallbackBitmapWidth  16
  55. #define FallbackBitmapHeight 16
  56. #define DefaultGrid          TRUE
  57. #define DefaultDashed        TRUE
  58. #define DefaultStippled      TRUE
  59. #define DefaultProportional  TRUE
  60. #define DefaultAxes          FALSE
  61. #define DefaultMargin        16
  62. #define DefaultSquareWidth   16
  63. #define DefaultSquareHeight  16
  64. #define DefaultFilename      ""
  65.  
  66. #define Offset(field) XtOffsetOf(BitmapRec, bitmap.field)
  67.  
  68. static XtResource resources[] = {
  69. {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
  70.      Offset(foreground_pixel), XtRString, XtDefaultForeground},
  71. {XtNhighlight, XtCHighlight, XtRPixel, sizeof(Pixel),
  72.      Offset(highlight_pixel), XtRString, XtDefaultForeground},
  73. {XtNframe, XtCFrame, XtRPixel, sizeof(Pixel),
  74.      Offset(frame_pixel), XtRString, XtDefaultForeground},
  75. {XtNgridTolerance, XtCGridTolerance, XtRDimension, sizeof(Dimension),
  76.      Offset(grid_tolerance), XtRImmediate, (XtPointer) DefaultGridTolerance},
  77. {XtNsize, XtCSize, XtRString, sizeof(String),
  78.      Offset(size), XtRImmediate, (XtPointer) DefaultBitmapSize},
  79. {XtNdashed, XtCDashed, XtRBoolean, sizeof(Boolean),
  80.      Offset(dashed), XtRImmediate, (XtPointer) DefaultDashed},
  81. {XtNgrid, XtCGrid, XtRBoolean, sizeof(Boolean),
  82.      Offset(grid), XtRImmediate, (XtPointer) DefaultGrid},
  83. {XtNstippled, XtCStippled, XtRBoolean, sizeof(Boolean),
  84.      Offset(stippled), XtRImmediate, (XtPointer) DefaultStippled},
  85. {XtNproportional, XtCProportional, XtRBoolean, sizeof(Boolean),
  86.      Offset(proportional), XtRImmediate, (XtPointer) DefaultProportional},
  87. {XtNaxes, XtCAxes, XtRBoolean, sizeof(Boolean),
  88.      Offset(axes), XtRImmediate, (XtPointer) DefaultAxes},
  89. {XtNsquareWidth, XtCSquareWidth, XtRDimension, sizeof(Dimension),
  90.      Offset(squareW), XtRImmediate, (XtPointer) DefaultSquareWidth},
  91. {XtNsquareHeight, XtCSquareHeight, XtRDimension, sizeof(Dimension),
  92.      Offset(squareH), XtRImmediate, (XtPointer) DefaultSquareHeight},
  93. {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension),
  94.      Offset(margin), XtRImmediate, (XtPointer) DefaultMargin},
  95. {XtNxHot, XtCXHot, XtRPosition, sizeof(Position),
  96.      Offset(hot.x), XtRImmediate, (XtPointer) NotSet},
  97. {XtNyHot, XtCYHot, XtRPosition, sizeof(Position),
  98.      Offset(hot.y), XtRImmediate, (XtPointer) NotSet},
  99. {XtNbutton1Function, XtCButton1Function, XtRButtonFunction, sizeof(int),
  100.      Offset(button_function[0]), XtRImmediate, (XtPointer) Set},
  101. {XtNbutton2Function, XtCButton2Function, XtRButtonFunction, sizeof(int),
  102.      Offset(button_function[1]), XtRImmediate, (XtPointer) Invert},
  103. {XtNbutton3Function, XtCButton3Function, XtRButtonFunction, sizeof(int),
  104.      Offset(button_function[2]), XtRImmediate, (XtPointer) Clear},
  105. {XtNbutton4Function, XtCButton4Function, XtRButtonFunction, sizeof(int),
  106.      Offset(button_function[3]), XtRImmediate, (XtPointer) Clear},
  107. {XtNbutton5Function, XtCButton5Function, XtRButtonFunction, sizeof(int),
  108.      Offset(button_function[4]), XtRImmediate, (XtPointer) Clear},
  109. {XtNfilename, XtCFilename, XtRString, sizeof(String),
  110.      Offset(filename), XtRImmediate, (XtPointer) DefaultFilename},
  111. {XtNbasename, XtCBasename, XtRString, sizeof(String),
  112.      Offset(basename), XtRImmediate, (XtPointer) DefaultFilename},
  113. {XtNdashes, XtCDashes, XtRBitmap, sizeof(Pixmap),
  114.      Offset(dashes), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
  115. {XtNstipple, XtCStipple, XtRBitmap, sizeof(Pixmap),
  116.      Offset(stipple), XtRImmediate, (XtPointer) XtUnspecifiedPixmap},
  117. };
  118. #undef Offset
  119.  
  120. void BWDebug();
  121. void BWChangeNotify();
  122. void BWSetChanged();
  123. void BWAbort();
  124. void BWUp();
  125. void BWDown();
  126. void BWLeft();
  127. void BWRight();
  128. void BWFold();
  129. void BWFlipHoriz();
  130. void BWFlipVert();
  131. void BWRotateRight();
  132. void BWRotateLeft();
  133. void BWSet();
  134. void BWClear();
  135. void BWInvert();
  136. void BWUndo();
  137. void BWRedraw();
  138. void BWTMark();
  139. void BWTMarkAll();
  140. void BWTUnmark();
  141. void BWTPaste();
  142.  
  143. static XtActionsRec actions[] =
  144. {
  145. {"mark",               BWTMark},
  146. {"mark-all",           BWTMarkAll},
  147. {"unmark",             BWTUnmark},
  148. {"paste",              BWTPaste},
  149. {"bw-debug",           BWDebug},
  150. {"abort",              BWAbort},
  151. {"store-to-buffer",    BWStoreToBuffer},
  152. {"change-notify",      BWChangeNotify},
  153. {"set-changed",        BWSetChanged},
  154. {"up",                 BWUp},
  155. {"down",               BWDown},
  156. {"left",               BWLeft},
  157. {"right",              BWRight},
  158. {"fold",               BWFold},
  159. {"flip-horiz",         BWFlipHoriz},
  160. {"flip-vert",          BWFlipVert},
  161. {"rotate-right",       BWRotateRight},
  162. {"rotate-left",        BWRotateLeft},
  163. {"set",                BWSet},
  164. {"clear",              BWClear},
  165. {"invert",             BWInvert},
  166. {"undo",               BWUndo},
  167. {"redraw",             BWRedraw},
  168. };
  169.  
  170. static char translations1[] =
  171. "\
  172. Shift<Btn1Down>: mark()\n\
  173. Shift<Btn2Down>: mark-all()\n\
  174. Shift<Btn3Down>: unmark()\n\
  175. Ctrl<BtnDown>:   paste()\n\
  176. Ctrl<Key>l: redraw()\n\
  177. <Key>d:     bw-debug()\n\
  178. <Key>a:     abort()\n\
  179. <Key>Up:    store-to-buffer()\
  180.             up()\
  181.             change-notify()\
  182.             set-changed()\n\
  183. <Key>Down:  store-to-buffer()\
  184.             down()\
  185.             change-notify()\
  186.             set-changed()\n\
  187. <Key>Left:  store-to-buffer()\
  188.             left()\
  189.             change-notify()\
  190.             set-changed()\n\
  191. <Key>Right: store-to-buffer()\
  192.             right()\
  193.             change-notify()\
  194.             set-changed()\n\
  195. <Key>f:     store-to-buffer()\
  196.             fold()\
  197.             change-notify()\
  198.             set-changed()\n\
  199. <Key>h:     store-to-buffer()\
  200.             flip-horiz()\
  201.             change-notify()\
  202.             set-changed()\n\
  203. ";
  204.  
  205. static char translations2[] =
  206. "<Key>v:     store-to-buffer()\
  207.             flip-vert()\
  208.             change-notify()\
  209.             set-changed()\n\
  210. <Key>r:     store-to-buffer()\
  211.             rotate-right()\
  212.             change-notify()\
  213.             set-changed()\n\
  214. <Key>l:     store-to-buffer()\
  215.             rotate-left()\
  216.             change-notify()\
  217.             set-changed()\n\
  218. <Key>s:     store-to-buffer()\
  219.             set()\
  220.             change-notify()\
  221.             set-changed()\n\
  222. <Key>c:     store-to-buffer()\
  223.             clear()\
  224.             change-notify()\
  225.             set-changed()\n\
  226. <Key>i:     store-to-buffer()\
  227.             invert()\
  228.             change-notify()\
  229.             set-changed()\n\
  230. <Key>u:     undo()\
  231.             change-notify()\
  232.             set-changed()\n\
  233. ";
  234.  
  235. Atom targets[] = {
  236.     XA_BITMAP,
  237.     XA_PIXMAP
  238. };
  239.  
  240. #include "Requests.h"
  241.  
  242. static void ClassInitialize();
  243. static void Initialize();
  244. static void Redisplay();
  245. static void Resize();
  246. static void Destroy();
  247. static Boolean SetValues();
  248.  
  249. BitmapClassRec bitmapClassRec = {
  250. {   /* core fields */
  251.     /* superclass        */    (WidgetClass) &simpleClassRec,
  252.     /* class_name        */    "Bitmap",
  253.     /* widget_size        */    sizeof(BitmapRec),
  254.     /* class_initialize        */    ClassInitialize,
  255.     /* class_part_initialize    */    NULL,
  256.     /* class_inited        */    FALSE,
  257.     /* initialize        */    Initialize,
  258.     /* initialize_hook        */    NULL,
  259.     /* realize            */    XtInheritRealize,
  260.     /* actions            */    actions,
  261.     /* num_actions        */    XtNumber(actions),
  262.     /* resources        */    resources,
  263.     /* num_resources        */    XtNumber(resources),
  264.     /* xrm_class        */    NULLQUARK,
  265.     /* compress_motion        */    TRUE,
  266.     /* compress_exposure    */    FALSE,
  267.     /* compress_enterleave    */    TRUE,
  268.     /* visible_interest        */    TRUE,
  269.     /* destroy            */    Destroy,
  270.     /* resize            */    Resize,
  271.     /* expose            */    Redisplay,
  272.     /* set_values        */    SetValues,
  273.     /* set_values_hook        */    NULL,
  274.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  275.     /* get_values_hook        */    NULL,
  276.     /* accept_focus        */    NULL,
  277.     /* version            */    XtVersion,
  278.     /* callback_private        */    NULL,
  279.     /* tm_table            */    NULL , /* set in code */
  280.     /* query_geometry        */    XtInheritQueryGeometry,
  281.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  282.     /* extension        */    NULL,
  283.   },
  284.   { 
  285.     /* empty            */    XtInheritChangeSensitive,
  286.   },
  287.   {
  288.     /* targets                  */      targets,
  289.     /* num_trets                */      XtNumber(targets),
  290.     /* requests                 */      requests,
  291.     /* num_requests             */      XtNumber(requests),
  292.   }
  293. };
  294.  
  295. WidgetClass bitmapWidgetClass = (WidgetClass) &bitmapClassRec;
  296.     
  297. /* ARGSUSED */
  298.  
  299. void BWDebug(w)
  300.     Widget w;
  301. {
  302.     DEBUG ^= True;
  303. }
  304.  
  305. Pixmap BWGetPixmap(w) 
  306.     Widget w;
  307. {
  308.     BitmapWidget BW = (BitmapWidget) w;
  309.  
  310.     return GetPixmap(BW, BW->bitmap.zoom.image);
  311. }
  312.  
  313. Pixmap BWGetUnzoomedPixmap(w)
  314.     Widget w;
  315. {
  316.     BitmapWidget BW = (BitmapWidget) w;
  317.     GC gc;
  318.     Pixmap pix;
  319.     
  320.     if (BW->bitmap.zooming) {    
  321.     pix = XCreatePixmap(XtDisplay(w), XtWindow(w), 
  322.                 BW->bitmap.zoom.image->width, 
  323.                 BW->bitmap.zoom.image->height, 1);
  324.     if (!(gc = XCreateGC(XtDisplay(w), pix, 
  325.                  (unsigned long) 0, (XGCValues *) 0)))
  326.         return (Pixmap) None;
  327.     
  328.     XPutImage(XtDisplay(w), pix, gc, 
  329.           BW->bitmap.zoom.image, 
  330.           0, 0, 0, 0, 
  331.           BW->bitmap.zoom.image->width, 
  332.           BW->bitmap.zoom.image->height);
  333.     XPutImage(XtDisplay(w), pix, gc, 
  334.           BW->bitmap.image, 
  335.           0, 0, 
  336.           BW->bitmap.zoom.at_x,
  337.           BW->bitmap.zoom.at_y,
  338.           BW->bitmap.image->width, 
  339.           BW->bitmap.image->height);
  340.     }
  341.     else {
  342.     pix = XCreatePixmap(XtDisplay(w), XtWindow(w), 
  343.                 BW->bitmap.image->width, 
  344.                 BW->bitmap.image->height, 1);
  345.     if (! (gc = XCreateGC(XtDisplay(w), pix, 
  346.                   (unsigned long) 0, (XGCValues *) 0)))
  347.         return (Pixmap) None;
  348.     
  349.     XPutImage(XtDisplay(w), pix, gc, 
  350.           BW->bitmap.image, 
  351.           0, 0, 0, 0,
  352.           BW->bitmap.image->width, 
  353.           BW->bitmap.image->height);
  354.     }
  355.     XFreeGC(XtDisplay(w), gc);
  356.     return(pix);
  357. }
  358.  
  359. XImage *CreateBitmapImage();
  360.  
  361. XImage *ConvertToBitmapImage();
  362.  
  363. XImage *GetImage(BW, pixmap)
  364.     BitmapWidget BW;
  365.     Pixmap pixmap;
  366. {
  367.     Window root;
  368.     int x, y;
  369.     unsigned int width, height, border_width, depth;
  370.     XImage *source, *image;
  371.  
  372.     XGetGeometry(XtDisplay(BW), pixmap, &root, &x, &y,
  373.          &width, &height, &border_width, &depth);
  374.  
  375.     source = XGetImage(XtDisplay(BW), pixmap, x, y, width, height,
  376.              1, XYPixmap);
  377.  
  378.     image = ConvertToBitmapImage(BW, source);
  379.  
  380.     return image;
  381. }
  382.  
  383. XImage *CreateBitmapImage(BW, data, width, height)
  384.     BitmapWidget BW;
  385.     char *data;
  386.     Dimension width, height;
  387. {
  388.     XImage *image = XCreateImage(XtDisplay(BW),
  389.                  DefaultVisual(XtDisplay(BW), 
  390.                            DefaultScreen(XtDisplay(BW))),
  391.                  1, XYBitmap, 0, 
  392.                  data, width, height,
  393.                  8, ((int)width + 7) / 8);
  394.  
  395.     image->height = height;
  396.     image->width = width;
  397.     image->depth = 1;
  398.     image->xoffset = 0;
  399.     image->format = XYBitmap;
  400.     image->data = (char *)data;
  401.     image->byte_order = LSBFirst;
  402.     image->bitmap_unit = 8;
  403.     image->bitmap_bit_order = LSBFirst;
  404.     image->bitmap_pad = 8;
  405.     image->bytes_per_line = ((int)width + 7) / 8;
  406.  
  407.     return image;
  408. }
  409.  
  410. void DestroyBitmapImage(image)
  411.     XImage **image;
  412. {
  413.     /*XDestroyImage(*image);*/
  414.     if (image) {
  415.     if (*image) {
  416.         if ((*image)->data)
  417.         XtFree((*image)->data);
  418.         XtFree((char *)*image);
  419.     }
  420.     *image = NULL;
  421.     }
  422. }
  423.  
  424. XImage *BWGetImage(w)
  425.     Widget w;
  426. {
  427.     BitmapWidget BW = (BitmapWidget) w;
  428.  
  429.     return BW->bitmap.image;
  430. }
  431.  
  432. void BWChangeNotify(w, client_data, call_data)
  433.      Widget       w;
  434.      caddr_t      client_data;
  435.      caddr_t      call_data;
  436. {
  437.     BitmapWidget BW = (BitmapWidget) w;
  438.  
  439.     if (BW->bitmap.notify)
  440.     (*BW->bitmap.notify)(w, client_data, call_data);
  441. }
  442.  
  443. void BWNotify(w, proc)        /* ARGSUSED */
  444.      Widget   w;
  445.      void   (*proc)();
  446. {
  447.     BitmapWidget BW = (BitmapWidget) w;
  448.  
  449.     BW->bitmap.notify = proc;
  450. }
  451.  
  452. void BWSetChanged(w)
  453.     Widget w;
  454. {
  455.     BitmapWidget BW = (BitmapWidget) w;
  456.     
  457.     BW->bitmap.changed = True;
  458. }
  459.  
  460. Boolean BWQueryChanged(w)
  461.     Widget w;
  462. {
  463.     BitmapWidget BW = (BitmapWidget) w;
  464.     
  465.     return BW->bitmap.changed;
  466. }
  467.  
  468. void BWClearChanged(w)
  469.     Widget w;
  470. {
  471.     BitmapWidget BW = (BitmapWidget) w;
  472.     
  473.     BW->bitmap.changed = False;
  474. }
  475.  
  476. Boolean BWQueryStored(w)
  477.     Widget w;
  478. {
  479.     BitmapWidget BW = (BitmapWidget) w;
  480.     
  481.     return (BW->bitmap.storage != NULL);
  482. }
  483.  
  484. Boolean BWQueryStippled(w)
  485.     Widget w;
  486. {
  487.     BitmapWidget BW = (BitmapWidget) w;
  488.  
  489.     return BW->bitmap.stippled;
  490. }
  491.  
  492. void RedrawStippled(BW)
  493.      BitmapWidget(BW);
  494. {
  495.   XExposeEvent event;
  496.   
  497.   event.type = Expose;
  498.   event.display = XtDisplay((Widget)BW);
  499.   event.window = XtWindow((Widget)BW);
  500.   event.x = 0;
  501.   event.y = 0;
  502.   event.width = BW->core.width;
  503.   event.height = BW->core.height;
  504.   event.count = 0;
  505.   
  506.   BWRedrawMark((Widget)BW);
  507.   
  508.   BW->bitmap.stipple_change_expose_event = True; 
  509.   
  510.   XtDispatchEvent((XEvent *)&event);
  511.   
  512.   BW->bitmap.stipple_change_expose_event = False;
  513. }
  514.  
  515. void BWSwitchStippled(w)
  516.     Widget w;
  517. {
  518.     BitmapWidget BW = (BitmapWidget) w;
  519.  
  520.     RedrawStippled(BW);
  521.  
  522.     BW->bitmap.stippled ^= True;
  523.     XSetFillStyle(XtDisplay(BW), BW->bitmap.highlighting_gc,
  524.           (BW->bitmap.stippled ? FillStippled : FillSolid));
  525.  
  526.     RedrawStippled(BW);    
  527. }
  528.  
  529. void BWSelect(w, from_x, from_y, to_x, to_y, btime)
  530.     Widget w;
  531.     Position from_x, from_y,
  532.          to_x, to_y;
  533.     Time btime;
  534. {
  535.     BWMark(w, from_x, from_y, to_x, to_y);
  536.  
  537.     BWGrabSelection(w, btime);
  538. }
  539.  
  540. Boolean BWQueryAxes(w)
  541.     Widget w;
  542. {
  543.     BitmapWidget BW = (BitmapWidget) w;
  544.  
  545.     return BW->bitmap.axes;
  546. }
  547.  
  548. void BWSwitchAxes(w)
  549.      Widget w;
  550. {
  551.     BitmapWidget BW = (BitmapWidget) w;
  552.  
  553.     BW->bitmap.axes ^= True;
  554.     BWHighlightAxes(w);
  555. }
  556.  
  557. void BWAxes(w, _switch)
  558.     Widget w;
  559.     Boolean _switch;
  560. {
  561.     BitmapWidget BW = (BitmapWidget) w;
  562.     
  563.     if (BW->bitmap.axes != _switch)
  564.     BWSwitchAxes(w);
  565. }
  566.  
  567. void BWRedrawAxes(w)
  568.     Widget w;
  569. {
  570.     BitmapWidget BW = (BitmapWidget) w;
  571.     
  572.     if (BW->bitmap.axes)
  573.     BWHighlightAxes(w);
  574. }
  575.  
  576. void BWPutImage(w, display, drawable, gc, x, y)
  577.      BitmapWidget w;
  578.      Display     *display;
  579.      Drawable     drawable;
  580.      GC           gc;
  581.      Position     x, y;
  582. {
  583.     BitmapWidget BW = (BitmapWidget) w;
  584.  
  585.   XPutImage(display, drawable, gc, BW->bitmap.image,
  586.         0, 0, x, y, BW->bitmap.image->width, BW->bitmap.image->height);
  587. }
  588.  
  589. String StripFilename(filename)
  590.     String filename;
  591. {
  592.     char *begin = rindex (filename, '/');
  593.     char *end, *result;
  594.     int length;
  595.     
  596.     if (filename) {
  597.     begin = (begin ? begin + 1 : filename);
  598.     end = index (begin, '.'); /* change to rindex to allow longer names */
  599.     length = (end ? (end - begin) : strlen (begin));
  600.     result = (char *) XtMalloc (length + 1);
  601.     strncpy (result, begin, length);
  602.     result [length] = '\0';
  603.     return (result);
  604.     }
  605.     else
  606.     return (NULL);
  607. }
  608.  
  609. int XmuWriteBitmapDataToFile (filename, basename, 
  610.                   width, height, datap, x_hot, y_hot)
  611.     String filename, basename;
  612.     int width, height;
  613.     char *datap;
  614.     int x_hot, y_hot;
  615. {
  616.     FILE *file;
  617.     int i, data_length;
  618.     
  619.     data_length = Length(width, height);
  620.     
  621.     if(!filename || !strcmp(filename, "") || !strcmp(filename, "-")) {   
  622.     file = stdout;
  623.     filename = "dummy";
  624.     }
  625.     else
  626.         file = fopen(filename, "w+");
  627.     
  628.     if (!basename || !strcmp(basename, "") || !strcmp(basename, "-"))
  629.     basename = StripFilename(filename);
  630.     
  631.     if (file) {
  632.     fprintf(file, "#define %s_width %d\n", basename, width);
  633.     fprintf(file, "#define %s_height %d\n", basename, height);
  634.     if (QuerySet(x_hot, y_hot)) {
  635.         fprintf(file, "#define %s_x_hot %d\n", basename, x_hot);
  636.         fprintf(file, "#define %s_y_hot %d\n", basename, y_hot);
  637.     }
  638.     fprintf(file, "static char %s_bits[] = {\n   0x%02x",
  639.         basename, (unsigned char) datap[0]);
  640.     for(i = 1; i < data_length; i++) {
  641.         fprintf(file, ",");
  642.         fprintf(file, (i % 12) ? " " : "\n   ");
  643.         fprintf(file, "0x%02x", (unsigned char) datap[i]);
  644.     }
  645.     fprintf(file, "};\n");
  646.     
  647.     if (file != stdout)
  648.         fclose(file);
  649.  
  650.     return BitmapSuccess;
  651.     }
  652.     
  653.     return 1;
  654. }
  655.  
  656. /*
  657.  *
  658.  */
  659.  
  660.                 /* ARGSUSED */
  661. static void CvtStringToButtonFunction(args, num_args, from_val, to_val)
  662.     XrmValuePtr args;        /* not used */
  663.     Cardinal    *num_args;      /* not used */
  664.     XrmValuePtr from_val;
  665.     XrmValuePtr to_val;
  666. {
  667.   static button_function;
  668.   char lower_name[80];
  669.  
  670.   XmuCopyISOLatin1Lowered (lower_name, (char*)from_val->addr);
  671.   
  672.   if (!strcmp(lower_name, XtClear)) {
  673.     button_function = Clear;
  674.     to_val->addr = (caddr_t) &button_function;
  675.     to_val->size = sizeof(button_function);
  676.     return;
  677.   }
  678.   
  679.   if (!strcmp(lower_name, XtSet)) {
  680.     button_function = Set;
  681.     to_val->addr = (caddr_t) &button_function;
  682.     to_val->size = sizeof(button_function);
  683.     return;
  684.   }
  685.  
  686.   if (!strcmp(lower_name, XtInvert)) {
  687.     button_function = Invert;
  688.     to_val->addr = (caddr_t) &button_function;
  689.     to_val->size = sizeof(button_function);
  690.     return;
  691.   }
  692.   
  693.   XtStringConversionWarning(from_val->addr, XtRButtonFunction);
  694.   button_function = Clear;
  695.   to_val->addr = (caddr_t) &button_function;
  696.   to_val->size = sizeof(button_function);
  697.   
  698. }
  699.  
  700. void Refresh();
  701.  
  702. static void ClassInitialize()
  703. {
  704.   char *tm_table = XtMalloc(strlen(translations1) + strlen(translations2) + 1);
  705.   strcpy(tm_table, translations1);
  706.   strcat(tm_table, translations2);
  707.   bitmapClassRec.core_class.tm_table = tm_table;
  708.  
  709.   XawInitializeWidgetSet();
  710.   XtAddConverter(XtRString, XtRButtonFunction, CvtStringToButtonFunction,
  711.          NULL, 0);
  712.   DEBUG = False;
  713. }
  714.  
  715. static void SetSizeFromSizeResource(bw)
  716.      BitmapWidget bw;
  717. {
  718.   if (BWParseSize(bw->bitmap.size, 
  719.           &bw->bitmap.width,
  720.           &bw->bitmap.height)
  721.       ==
  722.       False) {
  723.     bw->bitmap.width = FallbackBitmapWidth;
  724.     bw->bitmap.height = FallbackBitmapHeight;
  725.     XtWarning("Cannot parse the size resource.  BitmapWidget");
  726.   }
  727. }
  728.  
  729. void TransferImageData();
  730.  
  731. /* ARGSUSED */
  732. static void Initialize(request, new, argv, argc)
  733.     BitmapWidget request, new;
  734.     ArgList argv;
  735.     Cardinal argc;
  736. {
  737.     XGCValues  values;
  738.     XtGCMask   mask;
  739.     char *image_data, *buffer_data;
  740.  
  741.     new->bitmap.stipple_change_expose_event = False;
  742.     new->bitmap.notify = NULL;
  743.     new->bitmap.cardinal = 0;
  744.     new->bitmap.current = 0;
  745.     new->bitmap.fold = False;
  746.     new->bitmap.changed = False;
  747.     new->bitmap.zooming = False;
  748.     new->bitmap.selection.own = False;
  749.     new->bitmap.selection.limbo = False;
  750.  
  751.     new->bitmap.request_stack = (BWRequestStack *)
  752.     XtMalloc(sizeof(BWRequestStack));
  753.  
  754.     new->bitmap.request_stack[0].request = NULL;
  755.     new->bitmap.request_stack[0].call_data = NULL;
  756.     new->bitmap.request_stack[0].trap = False;
  757.  
  758.     SetSizeFromSizeResource(new);
  759.  
  760.     new->core.width = new->bitmap.width * new->bitmap.squareW + 
  761.     2 * new->bitmap.margin;
  762.     new->core.height = new->bitmap.height * new->bitmap.squareH + 
  763.     2 * new->bitmap.margin;
  764.   
  765.     new->bitmap.hot.x = new->bitmap.hot.y = NotSet;
  766.     new->bitmap.buffer_hot.x = new->bitmap.buffer_hot.y = NotSet;
  767.   
  768.     new->bitmap.mark.from_x = new->bitmap.mark.from_y = NotSet;
  769.     new->bitmap.mark.to_x = new->bitmap.mark.to_y = NotSet;
  770.     new->bitmap.buffer_mark.from_x = new->bitmap.buffer_mark.from_y = NotSet;
  771.     new->bitmap.buffer_mark.to_x = new->bitmap.buffer_mark.to_y = NotSet;
  772.  
  773.     values.foreground = new->bitmap.foreground_pixel;
  774.     values.background = new->core.background_pixel;
  775.     values.foreground ^= values.background;
  776.     values.function = GXxor;
  777.     mask = GCForeground | GCBackground | GCFunction;
  778.     new->bitmap.drawing_gc = XCreateGC(XtDisplay(new), 
  779.                        RootWindow(XtDisplay(new), 
  780.                        DefaultScreen(XtDisplay(new))),
  781.                        mask, &values);
  782.  
  783.     values.foreground = new->bitmap.highlight_pixel;
  784.     values.background = new->core.background_pixel;
  785.     values.foreground ^= values.background;
  786.     values.function = GXxor;
  787.     mask = GCForeground | GCBackground | GCFunction;
  788.     if (new->bitmap.stipple != XtUnspecifiedPixmap)
  789.     {
  790.     values.stipple = new->bitmap.stipple;
  791.     mask |= GCStipple | GCFillStyle;
  792.     }
  793.     values.fill_style = (new->bitmap.stippled ? FillStippled : FillSolid);
  794.  
  795.     new->bitmap.highlighting_gc = XCreateGC(XtDisplay(new), 
  796.                         RootWindow(XtDisplay(new), 
  797.                            DefaultScreen(XtDisplay(new))), 
  798.                         mask, &values);
  799.  
  800.  
  801.     values.foreground = new->bitmap.frame_pixel;
  802.     values.background = new->core.background_pixel;
  803.     values.foreground ^= values.background;
  804.     mask = GCForeground | GCBackground | GCFunction;
  805.     if (new->bitmap.dashes != XtUnspecifiedPixmap)
  806.     {
  807.     values.stipple = new->bitmap.dashes;
  808.     mask |= GCStipple | GCFillStyle;
  809.     }
  810.     values.fill_style = (new->bitmap.dashed ? FillStippled : FillSolid);
  811.  
  812.     new->bitmap.frame_gc = XCreateGC(XtDisplay(new), 
  813.                      RootWindow(XtDisplay(new), 
  814.                         DefaultScreen(XtDisplay(new))),
  815.                      mask, &values);
  816.  
  817.     values.foreground = new->bitmap.highlight_pixel;
  818.     values.background = new->core.background_pixel;
  819.     values.foreground ^= values.background;
  820.     mask = GCForeground | GCBackground | GCFunction;
  821.     new->bitmap.axes_gc = XCreateGC(XtDisplay(new), 
  822.                      RootWindow(XtDisplay(new), 
  823.                         DefaultScreen(XtDisplay(new))),
  824.                      mask, &values);
  825.  
  826.     image_data = CreateCleanData(Length(new->bitmap.width, 
  827.                     new->bitmap.height));
  828.     buffer_data = CreateCleanData(Length(new->bitmap.width, 
  829.                      new->bitmap.height));
  830.  
  831.     new->bitmap.storage = NULL;
  832.     
  833.     new->bitmap.image = CreateBitmapImage(new, 
  834.                       image_data,
  835.                       new->bitmap.width,
  836.                       new->bitmap.height);
  837.     new->bitmap.buffer = CreateBitmapImage(new, 
  838.                        buffer_data,
  839.                        new->bitmap.width,
  840.                        new->bitmap.height);
  841.  
  842.     /* Read file */
  843.     {
  844.     int status;
  845.     XImage *image, *buffer;
  846.     unsigned char *image_data;
  847.     char *buffer_data;
  848.     unsigned int width, height;
  849.     int x_hot, y_hot;
  850.     
  851.     status = XmuReadBitmapDataFromFile(new->bitmap.filename, 
  852.                        &width, &height, &image_data,
  853.                        &x_hot, &y_hot);
  854.     if (status == BitmapSuccess) {
  855.         
  856.         buffer_data = CreateCleanData(Length(width, height));
  857.         
  858.         image = CreateBitmapImage(new, image_data, width, height);
  859.         buffer = CreateBitmapImage(new, buffer_data, width, height);
  860.     
  861.         TransferImageData(new->bitmap.image, buffer);
  862.     
  863.         DestroyBitmapImage(&new->bitmap.image);
  864.         DestroyBitmapImage(&new->bitmap.buffer);
  865.     
  866.         new->bitmap.image = image;
  867.         new->bitmap.buffer = buffer;
  868.         new->bitmap.width = width;
  869.         new->bitmap.height = height;
  870.         
  871.         new->bitmap.hot.x = x_hot;
  872.         new->bitmap.hot.y = y_hot;
  873.         
  874.         new->bitmap.changed = False;
  875.         new->bitmap.zooming = False;
  876.     }
  877.  
  878.     new->bitmap.filename = XtNewString(new->bitmap.filename);
  879.     
  880.     if (!strcmp(new->bitmap.basename, "")) {
  881.         new->bitmap.basename = StripFilename(new->bitmap.filename);
  882.     }
  883.     else
  884.       new->bitmap.basename = XtNewString(new->bitmap.basename);
  885.     }
  886.  
  887.     Resize(new);
  888. }
  889.  
  890.  
  891. /* returns False if the format is wrong */
  892. Boolean BWParseSize(size, width, height)
  893.      String size;
  894.      Dimension *width, *height;
  895. {
  896.   int x, y;
  897.   unsigned int w, h;
  898.   int status;
  899.  
  900.   status = XParseGeometry(size, &x, &y, &w, &h);
  901.  
  902.   if (status & (WidthValue | HeightValue)) {
  903.     *width = (Dimension) w;
  904.     *height = (Dimension) h;
  905.     return True;
  906.   }
  907.   else return False;
  908.  
  909. }
  910.  
  911.  
  912. Boolean BWQueryMarked(w)
  913.     Widget w;
  914. {
  915.     BitmapWidget BW = (BitmapWidget) w;
  916.  
  917.     return QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y);
  918. }
  919.  
  920. void FixMark(BW)
  921.     BitmapWidget BW;
  922. {
  923.     if (QuerySet(BW->bitmap.mark.from_x, BW->bitmap.mark.from_y)) {
  924.     BW->bitmap.mark.from_x = min(BW->bitmap.mark.from_x, 
  925.                      BW->bitmap.image->width);
  926.     BW->bitmap.mark.from_y = min(BW->bitmap.mark.from_y, 
  927.                      BW->bitmap.image->height);
  928.     BW->bitmap.mark.to_x = min(BW->bitmap.mark.to_x, 
  929.                    BW->bitmap.image->width);
  930.     BW->bitmap.mark.to_y = min(BW->bitmap.mark.to_y, 
  931.                    BW->bitmap.image->height);
  932.     
  933.     if((BW->bitmap.mark.from_x == BW->bitmap.mark.from_y) &&
  934.        (BW->bitmap.mark.to_x   == BW->bitmap.mark.to_y))
  935.         BW->bitmap.mark.from_x = 
  936.         BW->bitmap.mark.from_y =
  937.             BW->bitmap.mark.to_x = 
  938.             BW->bitmap.mark.to_y = NotSet;
  939.     }
  940. }
  941.  
  942. /* ARGSUSED */
  943. int BWStoreFile(w, filename, basename)
  944.     Widget w;
  945.     String filename, *basename;
  946. {
  947.     BitmapWidget BW = (BitmapWidget) w;
  948.     int status;
  949.     unsigned char *storage_data;
  950.     unsigned int width, height;
  951.     int x_hot, y_hot;
  952.     
  953.     status = XmuReadBitmapDataFromFile(filename, &width, &height,
  954.                        &storage_data, &x_hot, &y_hot);
  955.     if (status == BitmapSuccess) {
  956.  
  957.     DestroyBitmapImage(&BW->bitmap.storage);
  958.     
  959.     BW->bitmap.storage = CreateBitmapImage(BW, storage_data, width, height);
  960.  
  961.     return BitmapSuccess;
  962.     }
  963.     else
  964.     XtWarning(" read file failed.  BitmapWidget");
  965.     
  966.     return status;
  967. }
  968.  
  969. String BWUnparseStatus(w)
  970.     Widget w;
  971. {
  972.     BitmapWidget BW = (BitmapWidget) w;
  973.     
  974.     sprintf(BW->bitmap.status, 
  975.         "Filename: %s  Basename: %s  Size: %dx%d",
  976.         (strcmp(BW->bitmap.filename, "") ? BW->bitmap.filename : "<none>"),
  977.         (strcmp(BW->bitmap.basename, "") ? BW->bitmap.basename : "<none>"),
  978.         BW->bitmap.width, BW->bitmap.height);
  979.  
  980.     return BW->bitmap.status;
  981. }
  982.  
  983. void BWChangeFilename(w, str)
  984.     Widget w;
  985.     String str;
  986. {
  987.   BitmapWidget BW = (BitmapWidget) w;
  988.   
  989.   if (str) {
  990.     XtFree(BW->bitmap.filename);
  991.     BW->bitmap.filename = XtNewString( str);
  992.   }
  993. }
  994.  
  995. void BWChangeBasename(w, str)
  996.     Widget w;
  997.     String str;
  998. {
  999.   BitmapWidget BW = (BitmapWidget) w;
  1000.   
  1001.   if (str) {
  1002.     XtFree(BW->bitmap.basename);
  1003.     BW->bitmap.basename = XtNewString(str);
  1004.   }
  1005. }
  1006.  
  1007.  
  1008. int BWReadFile(w, filename, basename) /* ARGSUSED */
  1009.     Widget w;
  1010.     String filename, basename;
  1011. {
  1012.     BitmapWidget BW = (BitmapWidget) w;
  1013.     int status;
  1014.     XImage *image, *buffer;
  1015.     unsigned char *image_data;
  1016.     char *buffer_data;
  1017.     unsigned int width, height;
  1018.     int x_hot, y_hot;
  1019.     
  1020.     if (!filename)
  1021.     filename = BW->bitmap.filename;
  1022.  
  1023.     status = XmuReadBitmapDataFromFile(filename, &width, &height, &image_data,
  1024.                        &x_hot, &y_hot);
  1025.     if (status == BitmapSuccess) {
  1026.     
  1027.     buffer_data = CreateCleanData(Length(width, height));
  1028.     
  1029.     image = CreateBitmapImage(BW, image_data, width, height);
  1030.     buffer = CreateBitmapImage(BW, buffer_data, width, height);
  1031.     
  1032.     TransferImageData(BW->bitmap.image, buffer);
  1033.     
  1034.     DestroyBitmapImage(&BW->bitmap.image);
  1035.     DestroyBitmapImage(&BW->bitmap.buffer);
  1036.     
  1037.     BW->bitmap.image = image;
  1038.     BW->bitmap.buffer = buffer;
  1039.     BW->bitmap.width = width;
  1040.     BW->bitmap.height = height;
  1041.     
  1042.     BW->bitmap.hot.x = x_hot;
  1043.     BW->bitmap.hot.y = y_hot;
  1044.     
  1045.     BW->bitmap.changed = False;
  1046.     BW->bitmap.zooming = False;
  1047.     
  1048.     XtFree(BW->bitmap.filename);
  1049.     BW->bitmap.filename = XtNewString(filename);
  1050.     XtFree(BW->bitmap.basename);
  1051.     BW->bitmap.basename= XtNewString(StripFilename(filename));
  1052.  
  1053.     BWUnmark(w);
  1054.     
  1055.     Resize(BW);
  1056.  
  1057.     if (BW->core.visible) {
  1058.         XClearArea(XtDisplay(BW), XtWindow(BW),
  1059.                0, 0, 
  1060.                BW->core.width, BW->core.height,
  1061.                True);
  1062.     }
  1063.     
  1064.     return BitmapSuccess;
  1065.     }
  1066.     else
  1067.     XtWarning(" read file failed.  BitmapWidget");
  1068.     
  1069.     return status;
  1070. }
  1071.  
  1072. int BWSetImage(w, image)
  1073.     Widget w;
  1074.     XImage *image;
  1075. {
  1076.     BitmapWidget BW = (BitmapWidget) w;
  1077.     XImage *buffer;
  1078.     char *buffer_data;
  1079.     
  1080.     buffer_data = CreateCleanData(Length(image->width, image->height));
  1081.     buffer = CreateBitmapImage(BW, buffer_data, 
  1082.                    (Dimension) image->width, 
  1083.                    (Dimension) image->height);
  1084.     
  1085.     TransferImageData(BW->bitmap.image, buffer);
  1086.     
  1087.     DestroyBitmapImage(&BW->bitmap.image);
  1088.     DestroyBitmapImage(&BW->bitmap.buffer);
  1089.     
  1090.     BW->bitmap.image = image;
  1091.     BW->bitmap.buffer = buffer;
  1092.     BW->bitmap.width = image->width;
  1093.     BW->bitmap.height = image->height;
  1094.     
  1095.     Resize(BW);
  1096.     
  1097.     if (BW->core.visible) {
  1098.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1099.            0, 0, 
  1100.            BW->core.width, BW->core.height,
  1101.            True);    
  1102.     }
  1103. }
  1104.  
  1105. int BWWriteFile(w, filename, basename)
  1106.     Widget w;
  1107.     String filename, basename;
  1108. {
  1109.     BitmapWidget BW = (BitmapWidget) w;
  1110.     char *data;
  1111.     XImage *image;
  1112.     XPoint hot;
  1113.     int status;
  1114.     
  1115.     if (BW->bitmap.zooming) {
  1116.         data = XtMalloc(Length(BW->bitmap.zoom.image->width, 
  1117.                    BW->bitmap.zoom.image->height));
  1118.     bcopy(BW->bitmap.zoom.image->data, data,
  1119.           Length(BW->bitmap.zoom.image->width, 
  1120.              BW->bitmap.zoom.image->height));
  1121.     image = CreateBitmapImage(BW, data,
  1122.                   (Dimension) BW->bitmap.zoom.image->width,
  1123.                   (Dimension) BW->bitmap.zoom.image->height);
  1124.     CopyImageData(BW->bitmap.image, image, 
  1125.               0, 0, 
  1126.               BW->bitmap.image->width - 1,
  1127.               BW->bitmap.image->height - 1,
  1128.               BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y);
  1129.     
  1130.     if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) {
  1131.         hot.x = BW->bitmap.hot.x + BW->bitmap.zoom.at_x;
  1132.         hot.y = BW->bitmap.hot.y + BW->bitmap.zoom.at_y;
  1133.     }
  1134.     else
  1135.         hot = BW->bitmap.zoom.hot;
  1136.     }
  1137.     else {
  1138.     image = BW->bitmap.image;
  1139.     hot = BW->bitmap.hot;
  1140.     }
  1141.     
  1142.     if (!filename) filename = BW->bitmap.filename;
  1143.     else {
  1144.     XtFree(BW->bitmap.filename);
  1145.     BW->bitmap.filename = XtNewString(filename);
  1146.     XtFree(BW->bitmap.basename);
  1147.     BW->bitmap.basename= XtNewString(StripFilename(filename));
  1148.     }
  1149.     if (!basename) basename = BW->bitmap.basename;
  1150.     else {
  1151.     XtFree(BW->bitmap.basename);
  1152.     BW->bitmap.basename = XtNewString(basename);
  1153.     }
  1154.  
  1155.     if (DEBUG)
  1156.     fprintf(stderr, "Saving filename: %s %s\n", filename, basename);
  1157.  
  1158.     status = XmuWriteBitmapDataToFile(filename, basename,
  1159.                       image->width, image->height, image->data,
  1160.                       hot.x, hot.y);
  1161.     if (BW->bitmap.zooming)
  1162.     DestroyBitmapImage(&image);
  1163.     
  1164.     if (status == BitmapSuccess)
  1165.     BW->bitmap.changed = False;
  1166.     
  1167.     return status;
  1168. }
  1169.  
  1170. String BWGetFilename(w, str)
  1171.     Widget w;
  1172.     String *str;
  1173. {
  1174.     BitmapWidget BW = (BitmapWidget) w;
  1175.     
  1176.     *str = XtNewString(BW->bitmap.filename);
  1177.  
  1178.     return *str;
  1179. }
  1180.  
  1181. String BWGetFilepath(w, str)
  1182.     Widget w;
  1183.     String *str;
  1184. {
  1185.     BitmapWidget BW = (BitmapWidget) w;
  1186.     String end;
  1187.  
  1188.     *str = XtNewString(BW->bitmap.filename);
  1189.     end = rindex(*str, '/');
  1190.  
  1191.     if (end)
  1192.     *(end + 1) = '\0';
  1193.     else 
  1194.     **str = '\0';
  1195.  
  1196.     return *str;
  1197. }
  1198.  
  1199.  
  1200. String BWGetBasename(w, str)
  1201.     Widget w;
  1202.     String *str;
  1203. {
  1204.     BitmapWidget BW = (BitmapWidget) w;
  1205.     
  1206.     *str = XtNewString(BW->bitmap.basename);
  1207.  
  1208.     return *str;
  1209. }
  1210.  
  1211. void FixHotSpot(BW)
  1212.     BitmapWidget BW;
  1213. {
  1214.     if (!QueryInBitmap(BW, BW->bitmap.hot.x, BW->bitmap.hot.y))
  1215.     BW->bitmap.hot.x = BW->bitmap.hot.y = NotSet;
  1216. }
  1217.  
  1218. void ZoomOut(BW)
  1219.     BitmapWidget BW;
  1220. {
  1221.     CopyImageData(BW->bitmap.image, BW->bitmap.zoom.image, 
  1222.           0, 0, 
  1223.           BW->bitmap.image->width - 1,
  1224.           BW->bitmap.image->height - 1,
  1225.           BW->bitmap.zoom.at_x, BW->bitmap.zoom.at_y);
  1226.     
  1227.     DestroyBitmapImage(&BW->bitmap.image);
  1228.     DestroyBitmapImage(&BW->bitmap.buffer);
  1229.     
  1230.     BW->bitmap.image = BW->bitmap.zoom.image;
  1231.     BW->bitmap.buffer = BW->bitmap.zoom.buffer;
  1232.     BW->bitmap.width = BW->bitmap.image->width;
  1233.     BW->bitmap.height = BW->bitmap.image->height;
  1234.     BW->bitmap.fold = BW->bitmap.zoom.fold;
  1235.     BW->bitmap.changed |= BW->bitmap.zoom.changed;
  1236.     BW->bitmap.grid = BW->bitmap.zoom.grid;
  1237.  
  1238.     if (QuerySet(BW->bitmap.hot.x, BW->bitmap.hot.y)) {
  1239.     BW->bitmap.hot.x += BW->bitmap.zoom.at_x;
  1240.     BW->bitmap.hot.y += BW->bitmap.zoom.at_y;
  1241.     }
  1242.     else
  1243.     BW->bitmap.hot = BW->bitmap.zoom.hot;
  1244.     
  1245.     BW->bitmap.mark.from_x = NotSet;
  1246.     BW->bitmap.mark.from_y = NotSet;
  1247.     BW->bitmap.mark.to_x = NotSet;
  1248.     BW->bitmap.mark.to_y = NotSet;
  1249.     BW->bitmap.zooming = False;
  1250. }    
  1251.  
  1252. void BWZoomOut(w)
  1253.     Widget w;
  1254. {
  1255.     BitmapWidget BW = (BitmapWidget) w;
  1256.     
  1257.     if (BW->bitmap.zooming) {
  1258.     ZoomOut(BW);
  1259.     
  1260.     Resize(BW);
  1261.     if (BW->core.visible)
  1262.         XClearArea(XtDisplay(BW), XtWindow(BW),
  1263.                0, 0, 
  1264.                BW->core.width, BW->core.height,
  1265.                True);
  1266.     }
  1267. }
  1268.  
  1269. void BWZoomIn();
  1270.  
  1271. void BWZoomMarked(w)
  1272.     Widget w;
  1273. {
  1274.     BitmapWidget BW = (BitmapWidget) w;
  1275.  
  1276.     BWZoomIn(w, 
  1277.          BW->bitmap.mark.from_x, BW->bitmap.mark.from_y,
  1278.          BW->bitmap.mark.to_x,   BW->bitmap.mark.to_y);
  1279. }
  1280.  
  1281. void BWZoomIn(w, from_x, from_y, to_x, to_y)
  1282.     Widget w;
  1283.     Position from_x, from_y,
  1284.          to_x, to_y;
  1285. {
  1286.     BitmapWidget BW = (BitmapWidget) w;
  1287.     XImage *image, *buffer;    
  1288.     Dimension width, height;
  1289.     char *image_data, *buffer_data;
  1290.   
  1291.     if (BW->bitmap.zooming)
  1292.     ZoomOut(BW);
  1293.     
  1294.     QuerySwap(from_x, to_x);
  1295.     QuerySwap(from_y, to_y);
  1296.     from_x = max(0, from_x);
  1297.     from_y = max(0, from_y);
  1298.     to_x = min(BW->bitmap.width - 1, to_x);
  1299.     to_y = min(BW->bitmap.height - 1, to_y);
  1300.     
  1301.     width = to_x - from_x + 1;
  1302.     height = to_y - from_y + 1;
  1303.  
  1304.     image_data = CreateCleanData(Length(width, height));
  1305.     buffer_data = CreateCleanData(Length(width, height));
  1306.  
  1307.     image = CreateBitmapImage(BW, image_data, width, height);
  1308.     buffer = CreateBitmapImage(BW, buffer_data, width, height);
  1309.  
  1310.     CopyImageData(BW->bitmap.image, image, from_x, from_y, to_x, to_y, 0, 0);
  1311.     CopyImageData(BW->bitmap.buffer, buffer, from_x, from_y, to_x, to_y, 0, 0);
  1312.     
  1313.     BW->bitmap.zoom.image = BW->bitmap.image;
  1314.     BW->bitmap.zoom.buffer = BW->bitmap.buffer;
  1315.     BW->bitmap.zoom.at_x = from_x;
  1316.     BW->bitmap.zoom.at_y = from_y;
  1317.     BW->bitmap.zoom.fold = BW->bitmap.fold;
  1318.     BW->bitmap.zoom.changed = BW->bitmap.changed;
  1319.     BW->bitmap.zoom.hot = BW->bitmap.hot;
  1320.     BW->bitmap.zoom.grid = BW->bitmap.grid;
  1321.  
  1322.     BW->bitmap.image = image;
  1323.     BW->bitmap.buffer = buffer;
  1324.     BW->bitmap.width = width;
  1325.     BW->bitmap.height = height;
  1326.     BW->bitmap.changed = False;
  1327.     BW->bitmap.hot.x -= from_x;
  1328.     BW->bitmap.hot.y -= from_y;
  1329.     BW->bitmap.mark.from_x = NotSet;
  1330.     BW->bitmap.mark.from_y = NotSet;
  1331.     BW->bitmap.mark.to_x = NotSet;
  1332.     BW->bitmap.mark.to_y = NotSet;
  1333.     BW->bitmap.zooming = True;
  1334.     BW->bitmap.grid = True; /* potencially true, could use a resource here */
  1335.  
  1336.     FixHotSpot(BW);
  1337.  
  1338.     Resize(BW);
  1339.     if (BW->core.visible)
  1340.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1341.            0, 0, 
  1342.            BW->core.width, BW->core.height,
  1343.            True);
  1344. }
  1345.  
  1346. XImage *ScaleBitmapImage();
  1347.  
  1348. void BWRescale(w, width, height)
  1349.     Widget w;
  1350.     Dimension width, height;
  1351. {
  1352.     BitmapWidget BW = (BitmapWidget) w;
  1353.     XImage *image, *buffer;
  1354.     char *buffer_data;
  1355.  
  1356.     if (BW->bitmap.zooming)
  1357.     ZoomOut(BW);
  1358.         
  1359.     image = ScaleBitmapImage(BW, BW->bitmap.image, 
  1360.                (double) width / (double) BW->bitmap.image->width,
  1361.                (double) height / (double) BW->bitmap.image->height);
  1362.  
  1363.     buffer_data = CreateCleanData(Length(image->width, image->height));
  1364.     buffer = CreateBitmapImage(BW, buffer_data, 
  1365.                    (Dimension) image->width, 
  1366.                    (Dimension) image->height);
  1367.     
  1368.     TransferImageData(BW->bitmap.buffer, buffer);
  1369.  
  1370.     DestroyBitmapImage(&BW->bitmap.image);
  1371.     DestroyBitmapImage(&BW->bitmap.buffer);
  1372.     
  1373.     BW->bitmap.image = image;
  1374.     BW->bitmap.buffer = buffer;
  1375.     BW->bitmap.width = image->width;
  1376.     BW->bitmap.height = image->height;
  1377.     
  1378.     FixHotSpot(BW);
  1379.     FixMark(BW);
  1380.  
  1381.     Resize(BW);
  1382.     if (BW->core.visible)
  1383.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1384.            0, 0, 
  1385.            BW->core.width, BW->core.height,
  1386.            True);
  1387. }
  1388.  
  1389. Boolean BWQueryZooming(w)
  1390.     Widget w;
  1391. {
  1392.     BitmapWidget BW = (BitmapWidget) w;
  1393.  
  1394.     return BW->bitmap.zooming;
  1395. }
  1396.  
  1397.  
  1398. static void ResizeGrid(BW, width, height)
  1399.      BitmapWidget BW;
  1400.      Dimension width, height;
  1401. {
  1402.   XImage *image, *buffer;
  1403.   char *image_data, *buffer_data;
  1404.   
  1405.   if (BW->bitmap.zooming)
  1406.     ZoomOut(BW);
  1407.   
  1408.   image_data = CreateCleanData(Length(width, height));
  1409.   buffer_data = CreateCleanData(Length(width, height));
  1410.   
  1411.   image = CreateBitmapImage(BW, image_data, width, height);
  1412.   buffer = CreateBitmapImage(BW, buffer_data, width, height);
  1413.   
  1414.   TransferImageData(BW->bitmap.image, image);
  1415.   TransferImageData(BW->bitmap.buffer, buffer);
  1416.   
  1417.   DestroyBitmapImage(&BW->bitmap.image);
  1418.   DestroyBitmapImage(&BW->bitmap.buffer);
  1419.   
  1420.   BW->bitmap.image = image;
  1421.   BW->bitmap.buffer = buffer;
  1422.   BW->bitmap.width = width;
  1423.   BW->bitmap.height = height;
  1424.   
  1425.   FixHotSpot(BW);
  1426.   FixMark(BW);
  1427. }
  1428.  
  1429. void BWResize(w, width, height)
  1430.     Widget w;
  1431.     Dimension width, height;
  1432. {
  1433.     BitmapWidget BW = (BitmapWidget) w;
  1434.  
  1435.     ResizeGrid(BW, width, height);
  1436.  
  1437.     Resize(BW);
  1438.     if (BW->core.visible)
  1439.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1440.            0, 0, 
  1441.            BW->core.width, BW->core.height,
  1442.            True);
  1443. }
  1444.  
  1445. static void Destroy(w)
  1446.     Widget w;
  1447. {
  1448.     BitmapWidget BW = (BitmapWidget) w;
  1449.  
  1450.     XFreeGC(XtDisplay(w), BW->bitmap.drawing_gc);
  1451.     XFreeGC(XtDisplay(w), BW->bitmap.highlighting_gc);
  1452.     XFreeGC(XtDisplay(w), BW->bitmap.frame_gc);
  1453.     XFreeGC(XtDisplay(w), BW->bitmap.axes_gc);
  1454.     BWRemoveAllRequests(w);
  1455.  
  1456.     XtFree(BW->bitmap.filename);
  1457.     XtFree(BW->bitmap.basename);
  1458. }
  1459.  
  1460.  
  1461. static void Resize(BW)
  1462.      BitmapWidget BW;
  1463. {
  1464.     Dimension squareW, squareH;
  1465.  
  1466.     squareW = max(1, ((int)BW->core.width - 2 * (int)BW->bitmap.margin) / 
  1467.           (int)BW->bitmap.width);
  1468.     squareH = max(1, ((int)BW->core.height - 2 * (int)BW->bitmap.margin) / 
  1469.           (int)BW->bitmap.height);
  1470.  
  1471.     if (BW->bitmap.proportional)
  1472.     BW->bitmap.squareW = BW->bitmap.squareH = min(squareW, squareH);
  1473.     else {
  1474.     BW->bitmap.squareW = squareW;
  1475.     BW->bitmap.squareH = squareH;
  1476.     }
  1477.     
  1478.     BW->bitmap.horizOffset = max((Position)BW->bitmap.margin, 
  1479.                  (Position)(BW->core.width - 
  1480.                         BW->bitmap.width * 
  1481.                         BW->bitmap.squareW) / 2);
  1482.     BW->bitmap.vertOffset = max((Position)BW->bitmap.margin, 
  1483.                 (Position)(BW->core.height - 
  1484.                        BW->bitmap.height * 
  1485.                        BW->bitmap.squareH) / 2);
  1486.  
  1487.     BW->bitmap.grid &= ((BW->bitmap.squareW > BW->bitmap.grid_tolerance) && 
  1488.             (BW->bitmap.squareH > BW->bitmap.grid_tolerance));
  1489. }
  1490.  
  1491. /* ARGSUSED */
  1492. static void Redisplay(BW, event, region)
  1493.      BitmapWidget BW;
  1494.      XEvent      *event;
  1495.      Region       region;
  1496. {
  1497.   if(event->type == Expose
  1498.      &&
  1499.      BW->core.visible)
  1500.     if (BW->bitmap.stipple_change_expose_event == False)
  1501.       Refresh(BW, 
  1502.           event->xexpose.x, event->xexpose.y,
  1503.           event->xexpose.width, event->xexpose.height);
  1504. }
  1505.  
  1506. void BWClip(w, x, y, width, height)
  1507.     Widget  w;
  1508.     Position x, y;
  1509.     Dimension width, height;
  1510. {
  1511.     Position      from_x, from_y,
  1512.                   to_x, to_y;
  1513.     BitmapWidget BW = (BitmapWidget) w;
  1514.     XRectangle rectangle;
  1515.   
  1516.     from_x = InBitmapX(BW, x);
  1517.     from_y = InBitmapY(BW, y);
  1518.     to_x = InBitmapX(BW, x + width);
  1519.     to_y = InBitmapY(BW, y + height);
  1520.     QuerySwap(from_x, to_x);
  1521.     QuerySwap(from_y, to_y);
  1522.     from_x = max(0, from_x);
  1523.     from_y = max(0, from_y);
  1524.     to_x = min(BW->bitmap.width - 1, to_x);
  1525.     to_y = min(BW->bitmap.height - 1, to_y);
  1526.  
  1527.     rectangle.x = InWindowX(BW, from_x);
  1528.     rectangle.y = InWindowY(BW, from_y);
  1529.     rectangle.width = InWindowX(BW, to_x  + 1) - InWindowX(BW, from_x);
  1530.     rectangle.height = InWindowY(BW, to_y + 1) - InWindowY(BW, from_y);
  1531.     XSetClipRectangles(XtDisplay(BW),
  1532.                BW->bitmap.highlighting_gc,
  1533.                0, 0,
  1534.                &rectangle, 1,
  1535.                Unsorted);
  1536.     XSetClipRectangles(XtDisplay(BW),
  1537.                BW->bitmap.drawing_gc,
  1538.                0, 0,
  1539.                &rectangle, 1,
  1540.                Unsorted);
  1541.     XSetClipRectangles(XtDisplay(BW),
  1542.                BW->bitmap.frame_gc,
  1543.                0, 0,
  1544.                &rectangle, 1,
  1545.                Unsorted);
  1546.     XSetClipRectangles(XtDisplay(BW),
  1547.                BW->bitmap.axes_gc,
  1548.                0, 0,
  1549.                &rectangle, 1,
  1550.                Unsorted);
  1551. }
  1552.  
  1553. void BWUnclip(w)
  1554.     Widget w;
  1555. {
  1556.     BitmapWidget BW = (BitmapWidget) w;
  1557.     XRectangle rectangle;
  1558.   
  1559.     rectangle.x = InWindowX(BW, 0);
  1560.     rectangle.y = InWindowY(BW, 0);
  1561.     rectangle.width = InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0);
  1562.     rectangle.height = InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0);
  1563.     XSetClipRectangles(XtDisplay(BW),
  1564.                BW->bitmap.highlighting_gc,
  1565.                0, 0,
  1566.                &rectangle, 1,
  1567.                Unsorted);
  1568.     XSetClipRectangles(XtDisplay(BW),
  1569.                BW->bitmap.drawing_gc,
  1570.                0, 0,
  1571.                &rectangle, 1,
  1572.                Unsorted);
  1573.     XSetClipRectangles(XtDisplay(BW),
  1574.                BW->bitmap.frame_gc,
  1575.                0, 0,
  1576.                &rectangle, 1,
  1577.                Unsorted);
  1578.     XSetClipRectangles(XtDisplay(BW),
  1579.                BW->bitmap.axes_gc,
  1580.                0, 0,
  1581.                &rectangle, 1,
  1582.                Unsorted);
  1583. }
  1584.  
  1585. void Refresh(BW, x, y, width, height)
  1586.     BitmapWidget BW;
  1587.     Position     x, y;
  1588.     Dimension    width, height;
  1589. {
  1590.     XRectangle rectangle;
  1591.  
  1592.     rectangle.x = min(x, InWindowX(BW, InBitmapX(BW, x)));
  1593.     rectangle.y = min(y, InWindowY(BW, InBitmapY(BW, y)));
  1594.     rectangle.width = max(x + width,
  1595.              InWindowX(BW, InBitmapX(BW, x + width)+1)) - rectangle.x;
  1596.     rectangle.height = max(y + height,
  1597.              InWindowY(BW, InBitmapY(BW, y + height)+1)) - rectangle.y;
  1598.     
  1599.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1600.            rectangle.x, rectangle.y,
  1601.            rectangle.width, rectangle.height,
  1602.            False);
  1603.  
  1604.     XSetClipRectangles(XtDisplay(BW),
  1605.                BW->bitmap.frame_gc,
  1606.                0, 0,
  1607.                &rectangle, 1,
  1608.                Unsorted);
  1609.  
  1610.     XDrawRectangle(XtDisplay(BW), XtWindow(BW),
  1611.            BW->bitmap.frame_gc,
  1612.            InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
  1613.            InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, 
  1614.            InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
  1615.  
  1616.     BWClip((Widget) BW, x, y, width, height);
  1617.  
  1618.     BWRedrawGrid((Widget) BW, x, y, width, height);
  1619.  
  1620.     BWRedrawSquares((Widget) BW, x, y, width, height);
  1621.  
  1622.     BWRedrawMark((Widget) BW);
  1623.     BWRedrawHotSpot((Widget) BW);
  1624.     BWRedrawAxes((Widget) BW);
  1625.     BWUnclip((Widget) BW);
  1626. }
  1627.  
  1628. Boolean BWQueryGrid(w)
  1629.     Widget w;
  1630. {
  1631.     BitmapWidget BW = (BitmapWidget) w;
  1632.  
  1633.     return BW->bitmap.grid;
  1634. }
  1635.  
  1636. void BWSwitchGrid(w)
  1637.     Widget w;
  1638. {
  1639.     BitmapWidget BW = (BitmapWidget) w;
  1640.     BW->bitmap.grid ^= TRUE;
  1641.     BWDrawGrid(w,
  1642.            0, 0,
  1643.            BW->bitmap.image->width - 1, BW->bitmap.image->height - 1);
  1644. }
  1645.  
  1646. void BWGrid(w, _switch)
  1647.     Widget w;
  1648.     Boolean _switch;
  1649. {
  1650.     BitmapWidget BW = (BitmapWidget) w;
  1651.     
  1652.     if (BW->bitmap.grid != _switch)
  1653.     BWSwitchGrid(w);
  1654. }
  1655.  
  1656. Boolean BWQueryDashed(w)
  1657.     Widget w;
  1658. {
  1659.     BitmapWidget BW = (BitmapWidget) w;
  1660.  
  1661.     return (BW->bitmap.dashed);
  1662. }
  1663.  
  1664. void BWSwitchDashed(w)
  1665.     Widget w;
  1666. {
  1667.     BitmapWidget BW = (BitmapWidget) w;
  1668.     XRectangle rectangle;
  1669.  
  1670.     BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1);
  1671.  
  1672.     rectangle.x = 0;
  1673.     rectangle.y = 0;
  1674.     rectangle.width = BW->core.width;
  1675.     rectangle.height = BW->core.height;
  1676.  
  1677.     XSetClipRectangles(XtDisplay(BW),
  1678.                BW->bitmap.frame_gc,
  1679.                0, 0,
  1680.                &rectangle, 1,
  1681.                Unsorted);
  1682.  
  1683.     XDrawRectangle(XtDisplay(BW), XtWindow(BW),
  1684.            BW->bitmap.frame_gc,
  1685.            InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
  1686.            InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, 
  1687.            InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
  1688.     
  1689.     BW->bitmap.dashed ^= True;
  1690.     XSetFillStyle(XtDisplay(BW), BW->bitmap.frame_gc,
  1691.           (BW->bitmap.dashed ? FillStippled : FillSolid));
  1692.  
  1693.     XDrawRectangle(XtDisplay(BW), XtWindow(BW),
  1694.            BW->bitmap.frame_gc,
  1695.            InWindowX(BW, 0) - 1, InWindowY(BW, 0) - 1,
  1696.            InWindowX(BW, BW->bitmap.width) - InWindowX(BW, 0) + 1, 
  1697.            InWindowY(BW, BW->bitmap.height) - InWindowY(BW, 0) + 1);
  1698.  
  1699.     BWUnclip(w);
  1700.    
  1701.     BWRedrawGrid(w, 0, 0, BW->bitmap.width - 1, BW->bitmap.height - 1);
  1702. }
  1703.  
  1704. void BWDashed(w, _switch)
  1705.     Widget w;
  1706.     Boolean _switch;
  1707. {
  1708.     BitmapWidget BW = (BitmapWidget) w;
  1709.     
  1710.     if (BW->bitmap.dashed != _switch)
  1711.     BWSwitchDashed(w);
  1712. }
  1713.  
  1714. static Boolean SetValues(old, request, new, args, num_args) /* ARGSUSED */
  1715.      Widget old, request, new;
  1716.      ArgList args;
  1717.      Cardinal num_args;
  1718. {
  1719.   BitmapWidget oldbw = (BitmapWidget) old;
  1720.   BitmapWidget newbw = (BitmapWidget) new;
  1721.   Boolean resize = False;
  1722.   Boolean redisplay = False;
  1723.  
  1724. #define NE(field) (oldbw->field != newbw->field)
  1725.  
  1726.   if (NE(bitmap.grid))
  1727.     BWSwitchGrid(old);
  1728.  
  1729.   if (NE(bitmap.dashed))
  1730.     BWSwitchDashed(old);
  1731.  
  1732.   if (NE(bitmap.axes))
  1733.     BWSwitchAxes(old);
  1734.  
  1735.   if (NE(bitmap.stippled))
  1736.     BWSwitchStippled(old);
  1737.  
  1738.   if (NE(bitmap.proportional))
  1739.     resize = True;
  1740.  
  1741.   if (NE(bitmap.filename) || NE(bitmap.basename)  || NE(bitmap.size))
  1742.     BWChangeNotify(old, NULL, NULL);
  1743.  
  1744.   if (NE(bitmap.filename))
  1745.     if (newbw->bitmap.filename) {
  1746.       XtFree(oldbw->bitmap.filename);
  1747.       newbw->bitmap.filename = XtNewString(newbw->bitmap.filename);
  1748.     }
  1749.     else 
  1750.       newbw->bitmap.filename = oldbw->bitmap.filename;
  1751.  
  1752.   if (NE(bitmap.basename))
  1753.     if (newbw->bitmap.basename) {
  1754.       XtFree(oldbw->bitmap.basename);
  1755.       newbw->bitmap.basename = XtNewString(newbw->bitmap.basename);
  1756.     }
  1757.     else 
  1758.       newbw->bitmap.basename = oldbw->bitmap.basename;
  1759.   
  1760.   if (NE(bitmap.size)) {
  1761.     Dimension width, height;
  1762.     
  1763.     if (BWParseSize(newbw->bitmap.size, &width, &height)) { 
  1764.       ResizeGrid(newbw, width, height);
  1765.       resize = True;
  1766.     }
  1767.   }
  1768.   
  1769.   if (NE(bitmap.margin) || 
  1770.       NE(bitmap.grid_tolerance) ||
  1771.       NE(bitmap.squareW) ||
  1772.       NE(bitmap.squareH) ||
  1773.       NE(core.height) ||
  1774.       NE(core.width))
  1775.     resize = True;
  1776.  
  1777.   if (NE(bitmap.hot.x) || NE(bitmap.hot.y))
  1778.     BWSetHotSpot(old, newbw->bitmap.hot.x, newbw->bitmap.hot.y);
  1779.     
  1780.   if (NE(bitmap.foreground_pixel) || NE(core.background_pixel)) {
  1781.     XSetForeground(XtDisplay(new), 
  1782.            newbw->bitmap.drawing_gc,
  1783.            newbw->bitmap.foreground_pixel 
  1784.            ^ 
  1785.            newbw->core.background_pixel);
  1786.     redisplay = True;
  1787.   }
  1788.  
  1789.   if (NE(bitmap.frame_pixel) || NE(core.background_pixel)) {
  1790.     XSetForeground(XtDisplay(new), 
  1791.            newbw->bitmap.frame_gc,
  1792.            newbw->bitmap.frame_pixel
  1793.            ^ 
  1794.            newbw->core.background_pixel);
  1795.     redisplay = True;
  1796.   }
  1797.  
  1798.   if (NE(bitmap.dashes)) {
  1799.     XSetStipple(XtDisplay(new),
  1800.         newbw->bitmap.frame_gc,
  1801.         newbw->bitmap.dashes);
  1802.     redisplay = True;
  1803.   }
  1804.  
  1805.   if (NE(bitmap.highlight_pixel) || NE(core.background_pixel)) {
  1806.     RedrawStippled(newbw);
  1807.     XSetForeground(XtDisplay(new), 
  1808.            newbw->bitmap.highlighting_gc,
  1809.            newbw->bitmap.highlight_pixel
  1810.            ^ 
  1811.            newbw->core.background_pixel);
  1812.     RedrawStippled(newbw);
  1813.   }
  1814.  
  1815.   if (NE(bitmap.stipple)) {
  1816.     RedrawStippled(newbw);
  1817.     XSetStipple(XtDisplay(new),
  1818.         newbw->bitmap.highlighting_gc,
  1819.         newbw->bitmap.stipple);
  1820.     RedrawStippled(newbw);
  1821.   }
  1822.   
  1823.   if (resize) Resize(newbw);
  1824.  
  1825.     return (redisplay || resize);
  1826.  
  1827. #undef NE
  1828. }
  1829.  
  1830. Boolean BWQueryProportional(w)
  1831.     Widget w;
  1832. {
  1833.     BitmapWidget BW = (BitmapWidget) w;
  1834.  
  1835.     return (BW->bitmap.proportional);
  1836. }
  1837.  
  1838. void BWSwitchProportional(w)
  1839.     Widget w;
  1840. {
  1841.     BitmapWidget BW = (BitmapWidget) w;
  1842.  
  1843.     BW->bitmap.proportional ^= True;
  1844.  
  1845.     Resize(BW);
  1846.     if (BW->core.visible)
  1847.     XClearArea(XtDisplay(BW), XtWindow(BW),
  1848.            0, 0, 
  1849.            BW->core.width, BW->core.height,
  1850.            True);
  1851. }
  1852.  
  1853. void BWProportional(w, _switch)
  1854.     Widget w;
  1855.     Boolean _switch;
  1856. {
  1857.     BitmapWidget BW = (BitmapWidget) w;
  1858.  
  1859.     if (BW->bitmap.proportional != _switch)
  1860.     BWSwitchProportional(w);
  1861. }
  1862.  
  1863.  
  1864. void BWTPaste(w, event)
  1865.     Widget  w;
  1866.     XEvent *event;
  1867. {
  1868.     BitmapWidget BW = (BitmapWidget) w;
  1869.  
  1870.     BWRequestSelection(w, event->xbutton.time, TRUE);
  1871.  
  1872.     if (!BWQueryStored(w))
  1873.     return;
  1874.     
  1875.     BWEngageRequest(w, RestoreRequest, False, 
  1876.             (char *)&(event->xbutton.state), sizeof(int));
  1877.     
  1878.     OnePointHandler(w,
  1879.            (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status,
  1880.            event);
  1881. }
  1882.  
  1883. void BWTMark(w, event)
  1884.     Widget  w;
  1885.     XEvent *event;
  1886. {
  1887.     BitmapWidget BW = (BitmapWidget) w;
  1888.  
  1889.     BWEngageRequest(w, MarkRequest, False,
  1890.             (char *)&(event->xbutton.state), sizeof(int));
  1891.     TwoPointsHandler(w,
  1892.             (BWStatus*) BW->bitmap.request_stack[BW->bitmap.current].status,
  1893.          event);
  1894.  
  1895. }
  1896.  
  1897. void BWTMarkAll(w, event)
  1898.     Widget w;
  1899.     XEvent *event;
  1900. {
  1901.     BWMarkAll(w);
  1902.  
  1903.     BWGrabSelection(w, event->xkey.time);
  1904. }
  1905.  
  1906. void BWTUnmark(w)
  1907.     Widget w;
  1908. {
  1909.     BWUnmark(w);
  1910. }
  1911.  
  1912. /*****************************************************************************/
  1913.